package codediff.parse.report;

import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CoverageMergeClass {
    private String sourcefilename;
    private List<CoverageMethod> coverageMethods;
    private List<CoverageLine> coverageLines;
    private List<Counter> counters;

    public static List<CoverageMergeClass> mergePackages(List<CoverageClass> packageCoverageClasses,
                                                         List<CoverageSourceFile> packageSourceFiles) {
        Map<String, CoverageSourceFile> sourceFileMap = packageSourceFiles.stream()
                .collect(Collectors.toMap(CoverageSourceFile::getName, it -> it));
        Map<String, List<CoverageClass>> sameSourceClassMap = packageCoverageClasses.stream()
                .collect(Collectors.toMap(CoverageClass::getSourcefilename, Lists::newArrayList, (classesA, classesB) -> {
                    classesA.addAll(classesB);
                    return classesA;
                }));
        return sourceFileMap.entrySet().stream()
                .filter(sourceEntry -> sameSourceClassMap.containsKey(sourceEntry.getKey()))
                .map(sourceEntry -> {
                    List<CoverageClass> coverageClasses = sameSourceClassMap.get(sourceEntry.getKey());
                    return merge(coverageClasses, sourceEntry.getValue());
                })
                .collect(Collectors.toList());
    }

    public static CoverageMergeClass merge(List<CoverageClass> coverageClasses, CoverageSourceFile sourceFile) {
        List<CoverageMethod> coverageMethods = coverageClasses.stream()
                .map(CoverageClass::getCoverageMethods)
                .flatMap(List::stream)
                .collect(Collectors.toList());
        return CoverageMergeClass.builder()
                .sourcefilename(sourceFile.getName())
                .counters(sourceFile.getCounters())
                .coverageMethods(coverageMethods)
                .coverageLines(sourceFile.getLines())
                .build();
    }
}
